package com.glaze.edu.factory;

import com.glaze.edu.annotation.Autowired;
import com.glaze.edu.annotation.Component;
import com.glaze.edu.annotation.Repository;
import com.glaze.edu.annotation.Service;
import com.glaze.edu.utils.ClassUtil;
import com.sun.org.apache.regexp.internal.RE;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @Description:
 * @auther ZhouLiGuo
 * @Date 2020/10/15 3:51 上午:08
 * @Version 1.0
 */
public class BeanFactory {
    private final static Map<String, Object> map = new HashMap<>();

    static {
        //扫描包下的所有类
        Set<String> classNameSet = ClassUtil.getClassName("com.glaze.edu", true);
        try {
            Iterator<String> iterator = classNameSet.iterator();
            while (iterator.hasNext()) {
                String className = iterator.next();
                if(className.contains("servlet") || className.contains("annotation")){
                    iterator.remove();
                }else {
                    Annotation[] annotations = Class.forName(className).getAnnotations();
                    if (annotations == null || annotations.length == 0) {
                        iterator.remove();
                    }
                }
            }
            for (String className : classNameSet) {
                Class<?> aClass = Class.forName(className);
                String beanName = getBeanName(aClass);
                if (beanName != null) {
                    Object instance = aClass.newInstance();
                    map.put(beanName, instance);
                }
            }

            //实例化后注入属性
            for (String key : map.keySet()) {
                Class<?> aClass =map.get(key).getClass();
                Object o = aClass.newInstance();
                Field[] declaredFields = aClass.getDeclaredFields();
                for (Field declaredField : declaredFields) {
                    declaredField.setAccessible(true);
                    if (declaredField.isAnnotationPresent(Autowired.class)) {
                        String name = declaredField.getName();
                        Object o1 = map.get(name);
                        //设置属性的值 给 o
                        declaredField.set(o, o1);
                    }
                }
                map.put(key,o);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static String getBeanName(Class<?> aclass) {
        Service service = aclass.getAnnotation(Service.class);
        if (service != null) {
            return service.value();
        }
        Component component = aclass.getAnnotation(Component.class);
        if (component != null) {
            return component.value();
        }
        Repository repository = aclass.getAnnotation(Repository.class);
        if (repository != null) {
            return repository.value();
        }
        return null;
    }

    public static <T> T getBean(String beanName) {
        return (T) map.get(beanName);
    }


}
